//
//  RxCURDTableController.swift
//  DemoProject
//
//  Created by Hao on 2018/8/21.
//  Copyright © 2018年 hao. All rights reserved.

/// RxSwift tableview 和 collectionView 范例: http://www.hangge.com/blog/cache/category_72_4.html

import UIKit
import RxDataSources

/// 定义操作命令枚举
fileprivate enum TableEditingCommand {
    case setItems(items: [String])  //设置表格数据
    case addItem(item: String)  //新增数据
    case moveItem(from: IndexPath, to: IndexPath) //移动数据
    case deleteItem(IndexPath) //删除数据
}

///定义表格对应的ViewModel
fileprivate struct RxTableViewModel {
    //表格数据项
    fileprivate var items:[String]
    
    init(items: [String] = []) {
        self.items = items
    }
    
    //执行相应的命令，并返回最终的结果
    func execute(command: TableEditingCommand) -> RxTableViewModel {
        switch command {
        case .setItems(let items):
            print(info: "设置表格数据")
            return RxTableViewModel(items: items)
        case .addItem(let item):
            print(info: "新增数据项")
            var items = self.items
            items.append(item)
            return RxTableViewModel(items: items)
        case .moveItem(let from, let to):
            print(info: "移动数据项")
            var items = self.items
            items.insert(items.remove(at: from.row), at: to.row)
            return RxTableViewModel(items: items)
        case .deleteItem(let indexPath):
            print(info: "删除数据项")
            var items = self.items
            items.remove(at: indexPath.row)
            return RxTableViewModel(items: items)
        }
    }
}

class RxCURDTableController: BaseViewController {

    let disposeBag = DisposeBag()
    
    var isEditTest = true
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let tableView = UITableView(frame: self.view.bounds, style: .plain)
        self.view.addSubview(tableView)
        tableView.top = kStatusBarAndNaviHeight()
        tableView.height = self.view.height-tableView.top
        
        let add = UIBarButtonItem()
        add.title = "添加"
        let refresh = UIBarButtonItem()
        refresh.title = "刷新"
        let edit = UIBarButtonItem()
        edit.title = "编辑"
        self.navigationItem.rightBarButtonItems = [add, refresh, edit]
        edit.rx.tap.subscribe { [weak self] (_) in
            tableView.setEditing(self!.isEditTest, animated: true)
            self!.isEditTest = !self!.isEditTest
        }.disposed(by: disposeBag)
        
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        //表格模型
        let initialVM = RxTableViewModel()
        
        // 刷新数据
        let refreshCommand = refresh.rx.tap.asObservable()
            .startWith(())  // 这个为了页面初始化时会自动加载一次数据
            .flatMapLatest(getRandomResult)
            .map(TableEditingCommand.setItems)
        
        // 新增条目
        let addCommand = add.rx.tap.asObservable()
            .map{ "\(arc4random())" }
            .map(TableEditingCommand.addItem)
        
        // 移动位置
        let movedCommand = tableView.rx.itemMoved
            .map(TableEditingCommand.moveItem)
        
        // 删除条目
        let deleteCommand = tableView.rx.itemDeleted.asObservable()
            .map(TableEditingCommand.deleteItem)
        
        // 绑定表格数据
        Observable.of(refreshCommand, addCommand, movedCommand, deleteCommand)
            .merge()
            .scan(initialVM) { (vm: RxTableViewModel, command: TableEditingCommand) -> RxTableViewModel in
                return vm.execute(command: command)
            }
            .startWith(initialVM)
            .map { [AnimatableSectionModel(model: "", items: $0.items)] }
            .share(replay: 1)
            .bind(to: tableView.rx.items(dataSource: dataSource()))
            .disposed(by: disposeBag)
    }
    
    //创建表格数据源
    private func dataSource() -> RxTableViewSectionedAnimatedDataSource<AnimatableSectionModel<String, String>> {
        return RxTableViewSectionedAnimatedDataSource(
            //设置插入、删除、移动单元格的动画效果
            animationConfiguration: AnimationConfiguration(insertAnimation: .top,
                                                           reloadAnimation: .fade,
                                                           deleteAnimation: .left),
            configureCell: {
                (dataSource, tv, indexPath, element) in
                let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
                cell.textLabel?.text = "条目\(indexPath.row)：\(element)"
                return cell
        },
            canEditRowAtIndexPath: { _, _ in
                return true //单元格可删除
        },
            canMoveRowAtIndexPath: { _, _ in
                return true //单元格可移动
        }
        )
    }
    
    //获取随机数据
    private func getRandomResult() -> Observable<[String]> {
        print(info: "生成随机数据。")
        let items = (0 ..< 5).map {_ in
            "\(arc4random())"
        }
        return Observable.just(items)
    }

}
